package com.example.service;

import com.example.entity.Hotel;
import com.example.entity.Room;
import jakarta.annotation.Resource;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.time.DayOfWeek;
import java.time.LocalDate;
import java.time.Month;
import java.util.HashMap;
import java.util.Map;

/**
 * 房价制定服务
 */
@Service
public class PricingService {

    @Resource
    private HotelService hotelService;

    /**
     * 计算指定日期的房间价格
     * @param roomId 房间ID
     * @param date 入住日期
     * @return 计算后的价格
     */
    public BigDecimal calculateRoomPrice(Long roomId, LocalDate date, Room room) {
        if (room == null) {
            return BigDecimal.ZERO;
        }
        
        // 获取基础价格
        BigDecimal basePrice = room.getPrice();
        
        // 获取酒店信息及其价格因子
        Hotel hotel = hotelService.selectById(room.getHotelId());
        BigDecimal hotelFactor = hotel != null ? hotel.getPriceFactor() : BigDecimal.ONE;

        // 根据星级调整价格
        BigDecimal starRatingFactor = calculateStarRatingFactor(hotel);
        
        // 根据季节调整价格
        BigDecimal seasonFactor = calculateSeasonFactor(date);
        
        // 根据周末/工作日调整价格
        BigDecimal weekdayFactor = calculateWeekdayFactor(date);
        
        // 根据需求调整价格
        BigDecimal demandFactor = calculateDemandFactor(room, date);
        
        // 计算最终价格
        BigDecimal adjustedPrice = basePrice
                .multiply(hotelFactor)
                .multiply(starRatingFactor)
                .multiply(seasonFactor)
                .multiply(weekdayFactor)
                .multiply(demandFactor)
                .setScale(2, RoundingMode.HALF_UP);
        
        return adjustedPrice;
    }
    
    /**
     * 根据酒店星级计算价格因子
     */
    private BigDecimal calculateStarRatingFactor(Hotel hotel) {
        if (hotel == null || hotel.getStarRating() == null) {
            return BigDecimal.ONE;
        }
        
        // 星级越高，价格因子越大
        switch (hotel.getStarRating()) {
            case 5: return new BigDecimal("1.2");
            case 4: return new BigDecimal("1.1");
            case 3: return new BigDecimal("1.0");
            case 2: return new BigDecimal("0.9");
            default: return new BigDecimal("0.8");
        }
    }
    
    /**
     * 根据季节计算价格因子
     */
    private BigDecimal calculateSeasonFactor(LocalDate date) {
        Month month = date.getMonth();
        
        // 旺季（春节、暑假、国庆）
        if (month == Month.JANUARY || month == Month.FEBRUARY || 
            month == Month.JULY || month == Month.AUGUST || 
            month == Month.OCTOBER) {
            return new BigDecimal("1.3");
        }
        
        // 平季（5月、6月、9月、12月）
        if (month == Month.MAY || month == Month.JUNE || 
            month == Month.SEPTEMBER || month == Month.DECEMBER) {
            return new BigDecimal("1.1");
        }
        
        // 淡季（其他月份）
        return new BigDecimal("0.9");
    }
    
    /**
     * 根据工作日/周末计算价格因子
     */
    private BigDecimal calculateWeekdayFactor(LocalDate date) {
        DayOfWeek dayOfWeek = date.getDayOfWeek();
        
        // 周末（周五、周六）价格上浮
        if (dayOfWeek == DayOfWeek.FRIDAY || dayOfWeek == DayOfWeek.SATURDAY) {
            return new BigDecimal("1.2");
        }
        
        // 工作日（周日至周四）
        return BigDecimal.ONE;
    }
    
    /**
     * 根据市场需求计算价格因子
     * 这里简化处理，实际应用可以结合更多复杂数据
     */
    private BigDecimal calculateDemandFactor(Room room, LocalDate date) {
        // 模拟市场需求数据：库存越少，价格越高
        if (room.getQuantity() <= 2) {
            return new BigDecimal("1.3"); // 库存紧张，价格上浮30%
        } else if (room.getQuantity() <= 5) {
            return new BigDecimal("1.15"); // 库存较少，价格上浮15%
        } else if (room.getQuantity() >= room.getTotalQuantity() * 0.8) {
            return new BigDecimal("0.9"); // 库存充足（超过80%），价格下浮10%
        }
        
        return BigDecimal.ONE; // 正常需求
    }
    
    /**
     * 批量计算日期范围内的房间价格
     * @param roomId 房间ID
     * @param startDate 开始日期
     * @param endDate 结束日期（不含）
     * @return 日期到价格的映射
     */
    public Map<LocalDate, BigDecimal> calculateDateRangePrices(Long roomId, LocalDate startDate, LocalDate endDate) {
        Map<LocalDate, BigDecimal> priceMap = new HashMap<>();
        Room room = null;
        
        // 获取房间信息
        if (roomId != null) {
            room = hotelService.getRoomById(roomId);
        }
        
        if (room == null) {
            return priceMap;
        }
        
        // 计算每一天的价格
        LocalDate date = startDate;
        while (date.isBefore(endDate)) {
            BigDecimal price = calculateRoomPrice(roomId, date, room);
            priceMap.put(date, price);
            date = date.plusDays(1);
        }
        
        return priceMap;
    }
} 